import { constantRoutes } from '@/router'
import router from '@/router'
import Layout from '@/layout'
import { componentsMap } from '@/router/componentsMap'
import { NO_CACHED_NAME_LIST } from '@/router/noCached'
import { setButtonPermissions, getButtonPermissions,
  removeButtonPermissions, getRouterPermissions,
  removeRouterPermissions } from '@/utils/auth'

const routerStr = getRouterPermissions()
const routerPermissionArray = routerStr && JSON.parse(routerStr)
const routers = convertRouter(routerPermissionArray)
router.addRoutes(routers)

const buttonStr = getButtonPermissions()
const buttonPermissionArray = buttonStr && JSON.parse(buttonStr)

const state = {
  // 常量路由 + 动态路由
  routes: constantRoutes.concat(routers),
  // 动态路由
  dynamicRoutes: routers,
  // 按钮权限数组
  buttonPermission: buttonPermissionArray || []
}

const mutations = {
  SET_ROUTES: (state, routes) => {
    state.routes = routes
  },
  SET_DYNAMIC_ROUTES: (state, routes) => {
    state.dynamicRoutes = routes
  },
  SET_BUTTON_PERMISSION: (state, buttonPermission) => {
    state.buttonPermission = buttonPermission
  }
}

const actions = {
  /**
   * 动态路由
   */
  generateRoutes({ commit }) {
    return new Promise((resolve) => {
      // 菜单接口去除之后，直接从session中获取路由数据
      const routerStr = getRouterPermissions()
      const routerPermissionArray = routerStr && JSON.parse(routerStr)
      const accessedRouters = convertRouter(routerPermissionArray)
      commit('SET_DYNAMIC_ROUTES', accessedRouters)
      commit('SET_ROUTES', constantRoutes.concat(accessedRouters))
      resolve(accessedRouters)
    })
  },
  /**
   * 清空vuex routes (重置vue router用resetRouter)
   */
  clearRouters({ commit }) {
    return new Promise(resolve => {
      commit('SET_ROUTES', [])
      commit('SET_DYNAMIC_ROUTES', [])
      removeRouterPermissions()
      resolve()
    })
  },
  /**
   * 设置button权限(vuex & session storage)
   */
  setButtonPermission({ commit }, buttonPermission) {
    return new Promise(resolve => {
      if (buttonPermission) {
        commit('SET_BUTTON_PERMISSION', buttonPermission)
        setButtonPermissions(JSON.stringify(buttonPermission))
      }
      resolve()
    })
  },
  /**
   * 清空button权限(vuex & session storage)
   */
  clearButtonPermissions({ commit }) {
    return new Promise(resolve => {
      commit('SET_BUTTON_PERMISSION', [])
      removeButtonPermissions()
      resolve()
    })
  }
}

/**
 *将后台的路由表进行格式化
 * @param {*} asyncRouterMap
 */
function convertRouter(asyncRouterMap) {
  const accessedRouters = []
  if (asyncRouterMap) {
    asyncRouterMap.forEach(item => {
      const parent = generateRouter(item, true)
      const children = []
      if (item.children) {
        item.children.forEach(child => {
          children.push(generateRouter(child, false))
        })
      }
      parent.children = children
      accessedRouters.push(parent)
    })
    accessedRouters.push({ path: '*', component: () => import('@/views/error-page/404'), hidden: true })
  }
  return accessedRouters
}

function generateRouter(item, isParent) {
  const router = {
    path: isParent ? '/' + item.path : item.path,
    name: item.name,
    meta: { ...item.meta, noCache: isNoCache(item.name) },
    hidden: item.hidden,
    component: isParent ? Layout : componentsMap[item.name]
  }
  return router
}
function isNoCache(name) {
  return NO_CACHED_NAME_LIST.includes(name)
}
export default {
  namespaced: true,
  state,
  mutations,
  actions
}
